package com.binge.springboot.lesson21.service;

import com.binge.springboot.lesson21.annotation.MyColumn;
import com.binge.springboot.lesson21.annotation.Mytable;
import com.binge.springboot.lesson21.entity.User;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Title: UserService.java
 * @Package com.binge.springboot.lesson21.service
 * @Description: 用户业务类
 * @author: binge
 * @date 2020/2/27
 * @version V1.0
 */

public class UserService {
    /**
     * 通过用户对象生成查询SQL语句的方法
     * @param user  用户对象
     * @return 生成的sql语句
     */
    public static String createSql(User user){
        StringBuffer sb = new StringBuffer();
        //通过反射，获取用户的class对象
        Class cla = user.getClass();
        //判断是否添加了某种注解，这里判断是否添加了Mytable注解
        boolean hasAnnotation = cla.isAnnotationPresent(Mytable.class);
        //如果没有添加注解，则直接返回，因为没有添加注解，无法生成sql语句
        if(!hasAnnotation){
            return null;
        }
        //如果添加了注解，把此注解类型强制转换为Mytable
        Mytable mytable = (Mytable)cla.getAnnotation(Mytable.class);
        //这个就是给User类上添加注解时，传入的参数
        String tableName = mytable.value();
        //接下来便是，利用反射机制，遍历类的变量进行生成拼接sql语句
        sb.append("select * from ").append(tableName).append(" where 1=1 ");
        Field[] fields = cla.getDeclaredFields();
        for (Field field : fields){
            //判断字段是否添加了MyColumn注解
            hasAnnotation = field.isAnnotationPresent(MyColumn.class);
            if(!hasAnnotation){
                return null;
            }

            //此处将生成getXXX方法，然后利用反射机制，获取字段的值
            String fieldName = field.getName();
            String methodName = "get" + fieldName.substring(0,1).toUpperCase()
                    + fieldName.substring(1);

            //这个变量用户存储每个变量的数值
            //这部分代码就是利用反射机制获取每个变量的数值
            Object fieldValueObj = null;
            try{
                Method method = cla.getMethod(methodName);
                fieldValueObj = method.invoke(user);
            }catch (Exception e){
                e.printStackTrace();
            }

            //获取列上配置的参数名，这个一般是数据库的字段名
            MyColumn myColumn = (MyColumn)field.getAnnotation(MyColumn.class);
            String colName = myColumn.value();

            //拼接数据库的字段及值
            sb.append(" and ").append(colName).append("=").append(fieldValueObj);
        }

        //返回拼接好的sql
        return sb.toString();
    }

    public static void main(String[] args) {
        //创建一个user对象,只设置部分变量的值
        User user = new User();
        user.setUserId("12");
        user.setUserName("binge");
        String sql = UserService.createSql(user);
        System.out.println(sql);
    }
}
